package org.chipu.jnids.alert;

import java.io.File;
import java.io.InputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Nonnull;
import org.chipu.shared.interfaces.Loggeable;
import org.chipu.shared.util.singletons.LinuxUtils;

/** Listens events from snort through syslog file. */
public final class SyslogSnortListener implements Runnable, AlertListener, Loggeable {
	private Logger logger = Logger.getLogger(getClass().getName());
	private final File syslogFile;
	@Nonnull
	private final AlertProcessor<SnortEvent> processor;

	public SyslogSnortListener(AlertProcessor<SnortEvent> ap, File syslogFile) {
		if (ap == null || syslogFile == null || !syslogFile.exists())
			throw new IllegalArgumentException("Processor: " + ap + ". Log file: " + syslogFile);
		processor = ap;
		this.syslogFile = syslogFile;
	}

	@Override
	public void setLogger(Logger logger) {
		if (logger != null)
			this.logger = logger;
	}

	@Override
	public void run() {
		try {
			logger.fine("SnortListener started");
			Process process = LinuxUtils.runCommand("tail -f " + syslogFile.getAbsolutePath(), false, false, true);
			InputStream is = process.getInputStream();
			byte[] buffer = new byte[1024];
			for(int count = 0; (count = is.read(buffer)) >= 0;) {
				SnortEvent se = toEvent(new String(buffer, 0, count - 1));
				if (se != null)
					processor.eventArrived(se);
			}
		} catch(Exception ex) {
			logger.log(Level.WARNING, "", ex);
		}
		logger.fine(getClass().getSimpleName() + " stopped");
	}

	private SnortEvent toEvent(String s) {
		if (s.indexOf("snort") != -1)
			try {
				return SnortParser.parseSyslogLine(s);
			} catch(Exception ex) {
				logger.log(Level.WARNING, "Could not parse snort alert: " + s, ex);
			}
		return null;
	}
}